{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Za8-Nr5k11fh"
      },
      "source": [
        "##### Copyright 2018 The TensorFlow Authors."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "cellView": "form",
        "id": "Eq10uEbw0E4l"
      },
      "outputs": [],
      "source": [
        "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_3bi1D2IiCyW"
      },
      "source": [
        "# Naive forecasting"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "m_6H00ELiA57"
      },
      "source": [
        "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/examples/blob/master/courses/udacity_intro_to_tensorflow_for_deep_learning/l08c02_naive_forecasting.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://github.com/tensorflow/examples/blob/master/courses/udacity_intro_to_tensorflow_for_deep_learning/l08c02_naive_forecasting.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View source on GitHub</a>\n",
        "  </td>\n",
        "</table>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "vidayERjaO5q"
      },
      "source": [
        "## Setup"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "gqWabzlJ63nL"
      },
      "outputs": [],
      "source": [
        "import numpy as np\n",
        "import matplotlib.pyplot as plt"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "sJwA96JU00pW"
      },
      "outputs": [],
      "source": [
        "def plot_series(time, series, format=\"-\", start=0, end=None, label=None):\n",
        "    plt.plot(time[start:end], series[start:end], format, label=label)\n",
        "    plt.xlabel(\"Time\")\n",
        "    plt.ylabel(\"Value\")\n",
        "    if label:\n",
        "        plt.legend(fontsize=14)\n",
        "    plt.grid(True)\n",
        "    \n",
        "def trend(time, slope=0):\n",
        "    return slope * time\n",
        "\n",
        "def seasonal_pattern(season_time):\n",
        "    \"\"\"Just an arbitrary pattern, you can change it if you wish\"\"\"\n",
        "    return np.where(season_time < 0.4,\n",
        "                    np.cos(season_time * 2 * np.pi),\n",
        "                    1 / np.exp(3 * season_time))\n",
        "  \n",
        "def seasonality(time, period, amplitude=1, phase=0):\n",
        "    \"\"\"Repeats the same pattern at each period\"\"\"\n",
        "    season_time = ((time + phase) % period) / period\n",
        "    return amplitude * seasonal_pattern(season_time)\n",
        "    \n",
        "def white_noise(time, noise_level=1, seed=None):\n",
        "    rnd = np.random.RandomState(seed)\n",
        "    return rnd.randn(len(time)) * noise_level"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "yVo6CcpRaW7u"
      },
      "source": [
        "## Trend and Seasonality"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "BLt-pLiZ0nfB"
      },
      "outputs": [],
      "source": [
        "time = np.arange(4 * 365 + 1)\n",
        "\n",
        "slope = 0.05\n",
        "baseline = 10\n",
        "amplitude = 40\n",
        "series = baseline + trend(time, slope) + seasonality(time, period=365, amplitude=amplitude)\n",
        "\n",
        "noise_level = 5\n",
        "noise = white_noise(time, noise_level, seed=42)\n",
        "\n",
        "series += noise\n",
        "\n",
        "plt.figure(figsize=(10, 6))\n",
        "plot_series(time, series)\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "a1sQpPjhtj0G"
      },
      "source": [
        "All right, this looks realistic enough for now. Let's try to forecast it. We will split it into two periods: the training period and the validation period (in many cases, you would also want to have a test period). The split will be at time step 1000."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "_w0eKap5uFNP"
      },
      "outputs": [],
      "source": [
        "split_time = 1000\n",
        "time_train = time[:split_time]\n",
        "x_train = series[:split_time]\n",
        "time_valid = time[split_time:]\n",
        "x_valid = series[split_time:]"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "bjD8ncEZbjEW"
      },
      "source": [
        "## Naive Forecast"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "Pj_-uCeYxcAb"
      },
      "outputs": [],
      "source": [
        "naive_forecast = series[split_time - 1:-1]"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "JtxwHj9Ig0jT"
      },
      "outputs": [],
      "source": [
        "plt.figure(figsize=(10, 6))\n",
        "plot_series(time_valid, x_valid, label=\"Series\")\n",
        "plot_series(time_valid, naive_forecast, label=\"Forecast\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "fw1SP5WeuixH"
      },
      "source": [
        "Let's zoom in on the start of the validation period:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "D0MKg7FNug9V"
      },
      "outputs": [],
      "source": [
        "plt.figure(figsize=(10, 6))\n",
        "plot_series(time_valid, x_valid, start=0, end=150, label=\"Series\")\n",
        "plot_series(time_valid, naive_forecast, start=1, end=151, label=\"Forecast\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "35gIlQLfu0TT"
      },
      "source": [
        "You can see that the naive forecast lags 1 step behind the time series."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Uh_7244Gsxfx"
      },
      "source": [
        "Now let's compute the mean absolute error between the forecasts and the predictions in the validation period:"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "LjpLQeWY11H8"
      },
      "outputs": [],
      "source": [
        "errors = naive_forecast - x_valid\n",
        "abs_errors = np.abs(errors)\n",
        "mae = abs_errors.mean()\n",
        "mae"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "WGPBC9QttI1u"
      },
      "source": [
        "That's our baseline, now let's try a moving average."
      ]
    }
  ],
  "metadata": {
    "colab": {
      "collapsed_sections": [],
      "name": "l08c02_naive_forecasting.ipynb",
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
